package com.tupu.controller.admin;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tupu.common.PageResult;
import com.tupu.common.Result;
import com.tupu.entity.admin.*;
import com.tupu.entity.neo4j.*;
import com.tupu.service.admin.*;
import com.tupu.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;

/**
 * 实例构建接口
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/api/ontology")
public class NodeController {

    @Autowired(required = false)
    private LabelService labelService;

    @Autowired(required = false)
    private NodeService nodeService;

    @Autowired(required = false)
    private RelationService relationService;

    /**
     * 根据图谱绑定node_id 查询实例的id及名称
     *
     * @param nodeId
     * @return
     */
    @PostMapping("/listByNodeId")
    public Result<List<NodeSimple>> findByNodeId(@RequestParam(required = false) Long nodeId,
                                                 @RequestParam(required = false, defaultValue = "300") Long size) {
        try {
            List<NodeSimple> nodes = nodeService.findByNodeId(nodeId, size);
            return Result.ok(nodes);
        } catch (Exception e) {
            return Result.errorMessage(e.toString());
        }
    }

    /**
     * 通过实例id查询实例属性信息
     *
     * @param id
     * @return
     */
    @PostMapping("/listOne")
    public Result<NodeListOne> findNodeById(@RequestParam(required = false) Long id) {
        try {
            NodeListOne result = nodeService.findNodeById(id);
            return Result.ok(result);
        } catch (Exception e) {
            return Result.errorMessage(e.toString());
        }
    }

    /**
     * 根据图谱id和实例名称 label 查询节点，分页
     *
     * @param nodeId
     * @param label
     * @return
     */
    @PostMapping("/listByLabel")
    public Result searchNodeByName(@RequestParam(required = false, defaultValue = "1") Integer page,
                                   @RequestParam(required = false, defaultValue = "10") Integer size,
                                   @RequestParam(required = false) Long nodeId,
                                   @RequestParam(required = false) String label,
                                   @RequestParam(required = false) String case_name) {
        try {
            NodeListAll result = nodeService.searchNodeByName(page, size, nodeId, label, case_name);
            return Result.ok(result);
        } catch (Exception e) {
            return Result.errorMessage("错误信息:" + e.getMessage());
        }
    }

    /**
     * 新增实例
     *
     * @param node
     * @return
     */
    @PostMapping("/addNode")
    public Result addNode(@RequestBody(required = false) NodeSingle node) {
        try {
            String result = nodeService.createNode(node);
/*            if (result.equals("uid已存在")) {
                return Result.errorMessage("uid已存在,检查后重试");
            }*/
            return Result.ok("新增成功");
        } catch (Exception e) {
            return Result.errorMessage("新增失败，错误信息:" + e.getMessage());
        }
    }

    /**
     * 根据实例id删除节点,同时删除关系
     *
     * @param id
     * @return
     */
    @PostMapping("/delNode")
    public Result del(Long id) {
        try {
            nodeService.delNodeById(id);
            return Result.ok("删除成功");
        } catch (Exception e) {
            return Result.errorMessage("删除节点失败,错误信息:" + e.getMessage());
        }
    }

    /**
     * 修改节点属性信息
     *
     * @param node
     * @return
     */
    @PostMapping("/updateNode")
    public Result updateNode(@RequestBody(required = false) NodeSingle node) {
        try {
            nodeService.updateNode(node);
            return Result.ok("修改成功");
        } catch (Exception e) {
            return Result.errorMessage(e.getMessage());
        }
    }

    /**
     * 创建节点间关系
     *
     * @param startId
     * @param endId
     * @param typeId
     * @return
     */
    @PostMapping("/addRelation")
    public Result createRelation(@RequestParam(required = false) Long startId,
                                 @RequestParam(required = false) Long endId,
                                 @RequestParam(required = false) Long typeId) {
        try {
            nodeService.CreateRelation(startId, endId, typeId);
            return Result.ok("添加成功");
        } catch (Exception e) {
            return Result.errorMessage("请输入完整信息");
        }
    }

    /**
     * 根据关系id删除节点间关系
     *
     * @param relation_id
     * @return
     */
    @PostMapping("/delRelation")
    public Result deleteRelation(@RequestParam(required = false) Long relation_id) {
        try {
            nodeService.delRelationById(relation_id);
            return Result.ok("删除成功");
        } catch (Exception e) {
            return Result.errorMessage("删除关系失败，请重试:" + e.getMessage());
        }
    }

    /**
     * 根据关系id修改 节点间关系
     *
     * @param startId
     * @param endId
     * @param typeId
     * @param relation_id
     * @return
     */
    @PostMapping("/updateRelation")
    public Result updateRelation(@RequestParam(required = false) Long startId,
                                 @RequestParam(required = false) Long endId,
                                 @RequestParam(required = false) Long typeId,
                                 @RequestParam(required = false) Long relation_id) {
        try {
            nodeService.updateRelation(relation_id, startId, endId, typeId);
            return Result.ok("修改成功");
        } catch (Exception e) {
            return Result.errorMessage("修改失败，错误信息:" + e.getMessage());
        }
    }

    /**
     * 根据关系id，relation_id查询一条关系数据
     *
     * @param relation_id
     * @return
     */
    @PostMapping("/findByRelationId")
    public Result<RelationListAll> findByRelationId(@RequestParam(required = false) Long relation_id) {

        try {
            RelationListAll oneRelation = nodeService.findOneRelation(relation_id);
            return Result.ok(oneRelation);
        } catch (Exception e) {
            return Result.errorMessage(e.toString());
        }
    }

    /**
     * 根据关系名称 relationName、node_id 查询实例关系数据，分页
     *
     * @param page
     * @param size
     * @param relation_name
     * @param node_id
     * @return
     */
    @PostMapping("/findRelationByName")
    public Result findByRelationNameAndNodeId(@RequestParam(required = false, defaultValue = "1") Integer page,
                                              @RequestParam(required = false, defaultValue = "10") Integer size,
                                              @RequestParam(required = false) String relation_name,
                                              @RequestParam(required = false) Long node_id) {
        try {
            PageResult<RelationListAll> info = nodeService.findByRelationNameAndNodeId(page, size, relation_name, node_id);
            return Result.ok(info);
        } catch (Exception e) {
            return Result.errorMessage("查询实例关系指向失败，错误信息：" + e.getMessage());
        }
    }

    /**
     * 新增实例 可视化
     *
     * @param node
     * @return
     */
    @PostMapping("/addNodeVis")
    public Result<LabelVisualized> addNodeVis(@RequestBody(required = false) NodeSingle node) {
        try {
            LabelVisualized Vis = nodeService.addNodeVis(node);
            if (null == Vis.getRootId()) {
                return Result.errorMessage("新增失败");
            }
            return Result.ok(Vis);
        } catch (Exception e) {
            return Result.errorMessage("新增失败:" + e.getMessage());
        }
    }

    /**
     * 实例列表 可视化（默认查询100个节点）
     *
     * @param nodeId
     * @return
     */
    @PostMapping("/listVis")
    public Result nodeListVis(@RequestParam(required = false) Long nodeId,
                              @RequestParam(required = false, defaultValue = "100") Long size) {
        try {
            LabelVisualized Vis = nodeService.nodeListVis(nodeId, size);
            return Result.ok(Vis);
        } catch (Exception e) {
            return Result.errorMessage(e.toString());
        }
    }

    /**
     * 导入节点csv文件到linux目录
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/import")
    public Map<String, Object> importNode(@RequestParam(required = false) MultipartFile file) {
        try {
            Map<String, Object> map = FileUtil.importCSV(file);
            return map;
        } catch (IOException e) {
            Map<String, Object> result = new HashMap<>();
            result.put("status", "error");
            result.put("msg", "上传失败,错误信息:" + e.getMessage());
            return result;
        }
    }

    /**
     * 数据管理 列表显示 type_id(0:本体数据,1:关系数据,2:实例数据，3:实例关系),根据名字 模糊查询 (分页)
     *
     * @param type_id
     * @param name
     * @param node_id
     * @param page
     * @param size
     * @return
     */
    @PostMapping("/data")
    public Result dataManagement(@RequestParam(required = false) Long type_id,
                                 @RequestParam(required = false) String name,
                                 @RequestParam(required = false) Long node_id,
                                 @RequestParam(required = false, defaultValue = "1") Long page,
                                 @RequestParam(required = false, defaultValue = "10") Long size) {
        try {
            //本体、标签数据
            if (type_id == 0) {
                Page<LabelInfo> pageInfo = labelService.labelDataManagement(name, node_id, page, size);
                return Result.ok(pageInfo);
            }
            //标签关系数据
            if (type_id == 1) {
                Page<RelationBuildingInfo> pageInfo = labelService.labelRelationDataManagement(node_id, name, page, size);
                return Result.ok(pageInfo);
            }
            //实例数据
            if (type_id == 2) {
                PageResult<NodeSingle> info = nodeService.nodeDataManagement(name, node_id, page, size);
                return Result.ok(info);
            }
            //实例关系数据
            if (type_id == 3) {
                PageResult<RelationListAll> info = nodeService.nodeRelationDataManagement(name, node_id, page, size);
                return Result.ok(info);
            }
        } catch (Exception e) {
            log.info(e.getMessage());
        }
        return Result.ok();
    }

    /**
     * 数据管理 列表展示所有数据 不分页，前端封装导出数据 type_id(0:本体数据,1:关系数据,2:实例数据,3:实例关系数据)
     *
     * @param type_id
     * @param node_id
     * @return
     */
    @PostMapping("/dataAll")
    public Result dataManagementAll(@RequestParam(required = false) Long type_id,
                                    @RequestParam(required = false) Long node_id) {
        //本体、标签数据
        if (type_id == 0) {
            List<LabelInfo> labelLists = labelService.labelDataManagementAll(node_id);
            return Result.ok(labelLists);
        }
        //标签关系数据
        if (type_id == 1) {
            List<RelationBuildingInfo> record = relationService.labelRelationDataManagementAll(node_id);
            return Result.ok(record);
        }
        //实例数据
        if (type_id == 2) {
            List<NodeSingle> nodesList = nodeService.nodeDataManagementAll(node_id);
            return Result.ok(nodesList);
        }
        //实例关系数据
        if (type_id == 3) {
            List<RelationListAll> listAlls = nodeService.nodeRelationDataManagementAll(node_id);
            return Result.ok(listAlls);
        }
        return Result.ok();
    }

    /**
     * 根据实例id集合 删除节点
     *
     * @param ids
     * @return
     */
    @PostMapping("/delNodeByIds")
    public Result delNodeByIds(@RequestParam(required = false) List<Long> ids) {
        try {
            nodeService.delNodeByIds(ids);
            return Result.ok("删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.errorMessage("请输入要删除的节点id");
        }
    }

    /**
     * 根据关系id 集合 删除节点间关系
     *
     * @param ids
     * @return
     */
    @PostMapping("/delRelationByIds")
    public Result deleteRelationByIds(@RequestParam(required = false) List<Long> ids) {
        try {
            nodeService.delRelationByIds(ids);
            return Result.ok("删除成功");
        } catch (Exception e) {
            return Result.errorMessage("请输入要删除的关系id");
        }
    }

    /**
     * csv文件上传 上传的分类 (0:标签导入,1:标签关系导入,2:实例导入,3:实例关系)
     *
     * @param node_id
     * @param file_path
     * @param type_id
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public Result upload(@RequestParam(required = false) Long node_id,
                         @RequestParam(required = false) String file_name,
                         @RequestParam(required = false) String file_path,
                         @RequestParam(required = false) Long type_id) {
        if (type_id == 0) {
            try {
                labelService.addLabelAndProperty(file_path, node_id);
                return Result.ok();
            } catch (Exception e) {
                return Result.error("CSV文件读取异常:" + e.getMessage());
            }
        }
        if (type_id == 1) {
            try {
                relationService.addRelationAndBuild(file_path, node_id);
                return Result.ok();
            } catch (Exception e) {
                return Result.error("CSV文件读取异常:" + e.getMessage());
            }
        }
        if (type_id == 2) {
            try {
                if (file_path.endsWith("csv")) {
                    nodeService.addNode(file_path, node_id);
                }
                if (file_path.endsWith("docx")) {
                    nodeService.uploadByWord(file_path, node_id);
                }
                return Result.ok();
            } catch (Exception e) {
                return Result.error("文件读取异常" + e);
            }
        }
        if (type_id == 3) {
            try {
                List<String> list = FileUtil.cut(file_path);
                for (String s : list) {
                    nodeService.addNodeRelation(s, node_id);
                }
                return Result.ok();
            } catch (IOException e) {
                return Result.error("文件读取异常:" + e);
            }
        }
        return Result.error("请输入完整数据");
    }

    /**
     * 根据标签和属性查询所有属性值
     *
     * @param node_id
     * @param label_id
     * @param property_id
     * @return
     */
    @PostMapping("/allProperty")
    public Result findAllProperty(@RequestParam(required = false) Long node_id,
                                  @RequestParam(required = false) Long label_id,
                                  @RequestParam(required = false) Long property_id) {
        try {
            List<String> list = nodeService.findAllProperty(node_id, label_id, property_id);
            return Result.ok(list);
        } catch (Exception e) {
            return Result.errorMessage("错误信息:" + e.getMessage());
        }
    }

    /**
     * 实例节点检索 （可视化）
     *
     * @param node_id
     * @param case_id
     * @param name
     * @return
     */
    @PostMapping("/nodeSearch")
    public Result nodeSearch(@RequestParam(required = false) Long node_id,
                             @RequestParam(required = false) Long case_id,
                             @RequestParam(required = false) String name) {
        try {
            LabelVisualized Vis = nodeService.nodeSearch(node_id, case_id, name);
            return Result.ok(Vis);
        } catch (Exception e) {
            return Result.errorMessage("错误信息:" + e.getMessage());
        }
    }

    /**
     * 实例节点高级检索 （可视化）
     *
     * @param node_id
     * @param label_id
     * @param property_id
     * @param property
     * @return
     */
    @PostMapping("/nodeAdvancedSearch")
    public Result nodeAdvancedSearch(@RequestParam(required = false) Long node_id,
                                     @RequestParam(required = false) Long label_id,
                                     @RequestParam(required = false) Long property_id,
                                     @RequestParam(required = false) String property) {
        try {
            LabelVisualized Vis = nodeService.nodeAdvancedSearch(node_id, label_id, property_id, property);
            return Result.ok(Vis);
        } catch (Exception e) {
            return Result.errorMessage("错误信息:" + e.getMessage());
        }
    }

    /**
     * 根据图谱id，关系名称搜索 可视化显示
     *
     * @param node_id
     * @param relation
     * @return
     */
    @PostMapping("/relationSearch")
    public Result relationSearch(@RequestParam(required = false) Long node_id,
                                 @RequestParam(required = false) String relation) {
        try {
            LabelVisualized Vis = nodeService.relationSearch(node_id, relation);
            return Result.ok(Vis);
        } catch (Exception e) {
            return Result.errorMessage("错误信息:" + e.getMessage());
        }
    }

    /**
     * 实例节点关系高级搜索
     *
     * @param node_id
     * @param start_label
     * @param start_proId
     * @param start_property
     * @param end_label
     * @param end_proId
     * @param end_property
     * @param relation
     * @return
     */
    @PostMapping("/relationAdvancedSearch")
    public Result relationAdvancedSearch(@RequestParam(required = false) Long node_id,
                                         @RequestParam(required = false) Long start_label,
                                         @RequestParam(required = false) Long start_proId,
                                         @RequestParam(required = false) String start_property,
                                         @RequestParam(required = false) Long end_label,
                                         @RequestParam(required = false) Long end_proId,
                                         @RequestParam(required = false) String end_property,
                                         @RequestParam(required = false) String relation) {
        try {
            LabelVisualized Vis = nodeService.relationAdvancedSearch(node_id, start_label, start_proId, start_property, end_label, end_proId, end_property, relation);
            return Result.ok(Vis);
        } catch (Exception e) {
            return Result.errorMessage("错误信息:" + e.getMessage());
        }
    }

    /**
     * 最短路径功能可视化
     *
     * @param node_id
     * @param start_label
     * @param start_proId
     * @param start_property
     * @param end_label
     * @param end_proId
     * @param end_property
     * @return
     */
    @PostMapping("/shortestPathVis")
    public Result shortestPath(@RequestParam(required = false) Long node_id,
                               @RequestParam(required = false) Long start_label,
                               @RequestParam(required = false) Long start_proId,
                               @RequestParam(required = false) String start_property,
                               @RequestParam(required = false) Long end_label,
                               @RequestParam(required = false) Long end_proId,
                               @RequestParam(required = false) String end_property) {
        try {
            LabelVisualized Vis = nodeService.shortestPath(node_id, start_label, start_proId, start_property, end_label, end_proId, end_property);
            return Result.ok(Vis);
        } catch (Exception e) {
            return Result.errorMessage("错误信息:" + e.getMessage());
        }
    }

    /**
     * 切换可视化显示属性
     *
     * @param node_id
     * @return
     */
    @PostMapping("/changePropertyVis")
    public Result changePropertyVis(@RequestParam(required = false) Long node_id,
                                    @RequestParam(required = false) Long label_id,
                                    @RequestParam(required = false) Long property_id,
                                    @RequestParam(required = false) String property_name) {
        try {
            LabelVisualized Vis = nodeService.changePropertyVis(node_id, label_id, property_id, property_name);
            return Result.ok(Vis);
        } catch (Exception e) {
            return Result.errorMessage("切换失败，错误信息：" + e.getMessage());
        }
    }

    /**
     * 实例切换层级(type=1,一阶邻居;type=2,二阶邻居;type=3,三阶邻居)
     *
     * @param node_id
     * @param type
     * @param label_name
     * @param case_name
     * @return
     */
    @PostMapping("/levelVis")
    public Result levelVis(@RequestParam(required = false) Long node_id,
                           @RequestParam(required = false) Long type,
                           @RequestParam(required = false) String label_name,
                           @RequestParam(required = false) String case_id,
                           @RequestParam(required = false) String case_name) {
        try {
            LabelVisualized Vis = nodeService.levelVis(type, node_id, label_name, case_name, case_id);
            return Result.ok(Vis);
        } catch (Exception e) {
            return Result.errorMessage("错误信息:" + e.getMessage());
        }
    }

    /**
     * 查询节点id和名称
     *
     * @param node_id
     * @return
     */
    @PostMapping("/allNodeName")
    public Result allNodeName(@RequestParam(required = false) Long node_id) {
        try {
            List<NodeSimple> list = nodeService.allNode(node_id);
            return Result.ok(list);
        } catch (Exception e) {
            return Result.errorMessage("错误信息:" + e.getMessage());
        }
    }
}